<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>Vue3 钩子函数</title>
    <!--<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.0-beta.7/vue.global.js"></script>-->
    <script type="text/javascript" src="../js/vue.global.js"></script>

</head>
<body>
<!--vue 应用实例挂载到此ID上，这样它及其下面的标签才能使用 vue 语法获取数据-->
<!--双大括号和 v-text 指令都是取值进行填充, v-text 取值后会对标签的内容进行替换-->
<div id="rootApp" style="margin-left: 5%">
    <h3>钩子函数</h3>
    <ul>
        <li>在 Vue 实例生命周期的不同阶段被自动调用的函数，让开发者有机会在特定阶段运行自己的代码。</li>
        <li>最常用的有 mounted、created、updated、unmounted 等等。</li>
        <li>钩子函数不要使用箭头函数的方式编写。</li>
    </ul>
    {{msg}} &nbsp;
    <br/>
    <br/>
    <button type="button" style="font-size: 16px" v-on:click.prevent="myClick()">点 我(F12控制台看结果)</button>
    {{count}}
</div>

</body>

<script type="text/javascript">
    let count = 1;
    // 1、每个 Vue 应用都是通过用 createApp 函数创建一个新的应用实例开始, 用来在应用中注册"全局"组件
    // 2、传递给 createApp 的选项用于配置根组件
    // 3、应用实例暴露的大多数方法都会返回该同一实例，方便链式编程
    const App = Vue.createApp({
        //组件选项
        // data 定义数据, html 中可以进行获取
        data() {
            function myClick() {
                // this 指向组件实例(vm), 单纯的 count++ 是不会改变 html 中的数据的
                this.count++;
            }
            return {
                author: '蚩尤后裔',
                msg: 'Hello Vue!',
                count,
                myClick //自定义的事件函数同样需要进行返回
            }
        },

        // 会在实例初始化完成、props 解析之后、data() 和 computed 等选项处理之前立即调用。
        // 注意，组合式 API 中的 setup() 钩子会在所有选项式 API 钩子之前调用，beforeCreate() 也不例外。
        beforeCreate() {
            console.log("beforeCreate：在组件实例初始化完成之后立即调用。");
        },

        // 当这个钩子被调用时，以下内容已经设置完成：响应式数据、计算属性、方法和侦听器。
        // 然而，此时挂载阶段还未开始，因此 $el 属性仍不可用。
        // 通常用于发送 ajax 请求后台数据，然后给 data 赋值，实现数据的异步加载，数据的初始化。
        created() {
            // this 表示 vue 实例.
            console.log("created：在组件实例处理完所有与状态相关的选项后调用。" + this.msg);
            this.msg = this.msg + " 蚩尤后裔。";
        },

        // 当这个钩子被调用时，组件已经完成了其响应式状态的设置，但还没有创建 DOM 节点。它即将首次执行 DOM 渲染过程。
        // 这个钩子在服务端渲染时不会被调用。
        beforeMount() {
            console.log("beforeMount：在组件被挂载之前调用。" + this.msg);
        },

        /**
         * 组件在以下情况下被视为已挂载：
         * 所有同步子组件都已经被挂载。(不包含异步组件或 <Suspense> 树内的组件)
         * 其自身的 DOM 树已经创建完成并插入了父容器中。注意仅当根容器在文档中时，才可以保证组件 DOM 树也在文档中。
         * 这个钩子通常用于执行需要访问组件所渲染的 DOM 树相关的副作用，或是在服务端渲染应用中用于确保 DOM 相关代码仅在客户端被调用。
         * 这个钩子在服务端渲染时不会被调用。
         */
        mounted() {
            console.log("mounted：在组件被挂载之后调用。" + this.msg);
        },

        // 这个钩子可以用来在 Vue 更新 DOM 之前访问 DOM 状态。在这个钩子中更改状态也是安全的。
        // 这个钩子在服务端渲染时不会被调用。
        beforeUpdate() {
            console.log("beforeUpdate：在组件即将因为一个响应式状态变更而更新其 DOM 树之前调用。" + this.count);
        },

        /**
         * 父组件的更新钩子将在其子组件的更新钩子之后调用。
         * 这个钩子会在组件的任意 DOM 更新后被调用，这些更新可能是由不同的状态变更导致的。
         * 如果你需要在某个特定的状态更改后访问更新后的 DOM，请使用 nextTick() 作为替代。
         * 这个钩子在服务端渲染时不会被调用。
         * 警告：不要在 updated 钩子中更改组件的状态，这可能会导致无限的更新循环！
         */
        updated() {
            console.log("updated：在组件因为一个响应式状态变更而更新其 DOM 树之后调用。" + this.count);
        },

        // 在一个组件实例被卸载之前调用。
        // 当这个钩子被调用时，组件实例依然还保有全部的功能。
        // 这个钩子在服务端渲染时不会被调用。
        beforeUnmount() {

        },

        /**
         * 在一个组件实例被卸载之后调用。
         * 一个组件在以下情况下被视为已卸载：
         * 其所有子组件都已经被卸载。
         * 所有相关的响应式作用 (渲染作用以及 setup() 时创建的计算属性和侦听器) 都已经停止。
         * 可以在这个钩子中手动清理一些副作用，例如计时器、DOM 事件监听器或者与服务器的连接。
         * 这个钩子在服务端渲染时不会被调用。
         */
        unmounted() {

        },

        /**
         * 在捕获了后代组件传递的错误时调用。
         * 错误可以从以下几个来源中捕获：
         * * 组件渲染
         * * 事件处理器
         * * 生命周期钩子
         * * setup() 函数
         * * 侦听器
         * * 自定义指令钩子
         * * 过渡钩子
         * 这个钩子带有三个实参：错误对象、触发该错误的组件实例，以及一个说明错误来源类型的信息字符串。
         */
        errorCaptured() {

        },

        /**
         * 若组件实例是 <KeepAlive> 缓存树的一部分，当组件被插入到 DOM 中时调用。
         * 这个钩子在服务端渲染时不会被调用。
         */
        activated() {

        },

        /**
         * 若组件实例是 <KeepAlive> 缓存树的一部分，当组件从 DOM 中被移除时调用。
         * 这个钩子在服务端渲染时不会被调用。
         */
        deactivated() {

        },

        /**
         * 当组件实例在服务器上被渲染之前要完成的异步函数。
         * 如果这个钩子返回了一个 Promise，服务端渲染会在渲染该组件前等待该 Promise 完成。
         * 这个钩子仅会在服务端渲染中执行，可以用于执行一些仅在服务端才有的数据抓取过程。
         */
        serverPrefetch() {

        }


    });

    // 4、一个应用需要被挂载(mount)到一个 DOM 元素中，当挂载(mount)应用时，该组件被用作渲染的起点
    // 5、与大多数应用方法不同的是 mount 不返回应用本身，而是返回的根组件实例(vm)
    const rootViewModel = App.mount("#rootApp");


</script>
</html>
